package com.gxgeek.lock;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author gaoxing
 * @create 2017-12-13 上午10:25
 */
public class LockConditionDemo {

    private Lock lock = new ReentrantLock();
    private Condition condition = lock.newCondition();
    private Condition conditionA = lock.newCondition();
    private Condition conditionB = lock.newCondition();

    public static void main(String[] args) throws InterruptedException {

        //使用同一个LockConditionDemo对象，使得lock、condition一样
        LockConditionDemo demo = new LockConditionDemo();
//        oneToOne(demo);
        oneToMore(demo);
    }

    private static void oneToMore(LockConditionDemo demo) throws InterruptedException {
        new Thread(() -> demo.await(demo.conditionA), "thread1_conditionA").start();
        new Thread(() -> demo.await(demo.conditionB), "thread2_conditionB").start();
        new Thread(() -> demo.signal(demo.conditionA), "thread3_conditionA").start();
        System.out.println("稍等5秒再通知其他的线程！");
        Thread.sleep(5000);
        new Thread(() -> demo.signal(demo.conditionB), "thread4_conditionB").start();

    }
    private void await(Condition condition) {
        try {
            lock.lock();
            System.out.println("开始等待await！ ThreadName：" + Thread.currentThread().getName());
            condition.await();
            System.out.println("等待await结束！ ThreadName：" + Thread.currentThread().getName());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    private void signal(Condition condition) {
        lock.lock();
        System.out.println("发送通知signal！ ThreadName：" + Thread.currentThread().getName());
        condition.signal();
        lock.unlock();
    }

    private static void oneToOne(LockConditionDemo demo) throws InterruptedException {
        new Thread(() -> demo.await(), "thread1").start();
        Thread.sleep(3000);
        new Thread(() -> demo.signal(), "thread2").start();
    }

    private void await() {
        try {
            lock.lock();
            System.out.println("开始等待await！ ThreadName：" + Thread.currentThread().getName());
            condition.await();
            System.out.println("等待await结束！ ThreadName：" + Thread.currentThread().getName());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    private void signal() {
        lock.lock();
        System.out.println("发送通知signal！ ThreadName：" + Thread.currentThread().getName());
        condition.signal();
        lock.unlock();
    }
}


